<?php
/**
 * User: Drery
 * Date: 2015/12/24
 * Time: 11:15
 */

namespace backend\components\grid;

use Yii;
use backend\components\HtmlHelper;
use yii\grid\GridView;
use backend\components\grid\MyDataColumn;
use yii\helpers\Html;
use yii\helpers\Url;

class MyGridView extends GridView{
    const FILTER_POS_TOP = 'top';

    public $tableOptions = ['class'=>'table table-bordered table-hover'];
    public $layout = "<div class=\"box-header\">{top}</div><div class=\"box-body\">{summary}\n{items}</div><div class=\"box-footer\">{pager}</div>";
    public $filterPosition = self::FILTER_POS_TOP;
    public $dataColumnClass = 'backend\components\grid\MyDataColumn';
    public $topFilterOptions = ['class' => 'col-sm-6 no-padding'];
    public $topSearchOptions = ['class' => 'col-sm-3 col-sm-offset-1 no-padding'];
    public $topButtonOptions = ['class' => 'col-sm-2 no-padding'];
    public $topFilterTemplate = '';
    public $topSearchTemplate = '{key}';
    public $topButtonTemplate = '{add}';
    public $topButtons = [];
    public $topSearchInputPlaceholder;

    public function init()
    {
        parent::init();
        Html::addCssClass($this->topButtonOptions,'btn-group');
        $this->initTopButtons();
    }

    public function initTopButtons()
    {
        if (!isset($this->topButtons['add'])) {
            $this->topButtons['add'] = function ($url) {
                $options = ['class'=>'btn btn-sm btn-primary'];
                return Html::a('<i class="fa fa-fw fa-plus-square"></i>新增', $url, $options);
            };
        }
    }

    public function renderSection($name)
    {
        switch ($name) {
            case "{top}":
                return $this->renderTop();
            default:return parent::renderSection($name);

        }
    }

    public function renderTop()
    {
        $btns = $this->renderTopBtns();
        $filters = $this->renderFilters();
        $contents = array_filter([
            $btns,
            $filters
        ]);
        if ($this->filterPosition == self::FILTER_POS_TOP) {
            return Html::tag('div',implode("\n",$contents),$this->filterRowOptions);
        }
        return implode("\n",$contents);
    }

    public function renderTopBtns()
    {
        $content = preg_replace_callback('/\\{([\w\-\/]+)\\}/', function ($matches){
            $name = $matches[1];
            if (isset($this->topButtons[$name])) {
                $url = Url::toRoute([Yii::$app->controller->id.'/'.$name]);

                return call_user_func($this->topButtons[$name], $url);
            } else {
                return '';
            }
        }, $this->topButtonTemplate);
        if (!$content)
            return '';
        return Html::tag('div',$content,$this->topButtonOptions);
    }

    public function renderFilters()
    {
        if ($this->filterPosition == self::FILTER_POS_TOP) {
            if ($this->filterModel !== null) {
                $filterCells = [];
                $searchCells = [];
                foreach ($this->columns as $column) {
                    if (!$column instanceof MyDataColumn)
                        continue;
                    list($parentOptions, $filterContent, $combine, $isSearch) = $this->parseFilterInputOptions($column);
                    $tag = $column->renderFilterCell();
                    if ($tag != '&nbsp;') {
                        if (!$isSearch) {
                            if ($filterContent && $filterContent instanceof \Closure) {
                                if ($combine) {
                                    $prev = array_pop($filterCells);
                                    $filterCells[] = call_user_func($filterContent, $tag, $prev);
                                } else {
                                    $filterCells[] = call_user_func($filterContent, $tag);
                                }
                            } elseif ($parentOptions) {
                                $filterCells[] = Html::tag('div',$tag,$parentOptions);
                            } else {
                                $filterCells[] = $tag;
                            }
                        } else {
                            $options = ['class'=>'input-group input-group-sm'];
                            $button = '<span class="input-group-btn"><button class="btn btn-info btn-flat submit" type="button">搜索</button></span>';
                            $searchCells[] = Html::tag('div',$tag.$button,$options);
                        }
                    }
                }
                $filterTag = empty($filterCells) ? '' : Html::tag('div',implode('',$filterCells),$this->topFilterOptions);
                $searchTag = empty($searchCells) ? '' : Html::tag('div',implode('',$searchCells),$this->topSearchOptions);
                return $filterTag.$searchTag;
            } else {
                return '';
            }
        } else {
            parent::renderFilters();
        }
    }

    private function parseFilterInputOptions(MyDataColumn $column){
        // initialize filter setting options
        $parentOptions = [];
        $combine = false;
        $filterContent = false;
        $isSearch = false;
        if (!isset($column->filterInputOptions))
            return [$parentOptions, $filterContent, $combine, $isSearch];

        $options = $column->filterInputOptions;
        if (isset($options['parentOptions'])) {
            $parentOptions = $options['parentOptions'];
            unset($column->filterInputOptions['parentOptions']);
        }
        if (isset($options['isSearch'])) {
            $isSearch = $options['isSearch'];
            unset($column->filterInputOptions['isSearch']);
        }
        if (isset($options['filterContent'])) {
            $filterContent = $options['filterContent'];
            unset($column->filterInputOptions['filterContent']);
        }
        if (isset($options['combine'])) {
            $combine = $options['combine'];
            unset($column->filterInputOptions['combine']);
        }
        return [$parentOptions, $filterContent, $combine, $isSearch];
    }
}